import 'dart:math'; // 需要导入 math 库来使用 sqrt 函数

// --- 1. Instance Methods (Point Class) ---
class Point {
  final double x;
  final double y;

  // 构造函数
  Point(this.x, this.y);

  // 实例方法：计算到另一个点的距离
  double distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    // 使用 dart:math 库中的 sqrt 函数计算平方根
    return sqrt(dx * dx + dy * dy);
  }

  @override
  String toString() => 'Point($x, $y)';
}

// --- 2. Operators (Vector Class) ---
class Vector {
  final int x, y;

  // 构造函数
  Vector(this.x, this.y);

  // 定义 '+' 操作符
  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);

  // 定义 '-' 操作符
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // 重写 '==' 操作符
  // 注意：当重写 == 时，也应该重写 hashCode
  @override
  bool operator ==(Object other) =>
      other is Vector && x == other.x && y == other.y;

  // 重写 hashCode getter
  @override
  int get hashCode => Object.hash(x, y); // 使用 Object.hash 来生成哈希码

  @override
  String toString() => 'Vector($x, $y)';
}

// --- 3. Getters and Setters (Rectangle Class) ---
class Rectangle {
  double left, top, width, height;

  // 构造函数
  Rectangle(this.left, this.top, this.width, this.height);

  // 定义计算属性 right 的 getter
  double get right => left + width;

  // 定义计算属性 right 的 setter
  set right(double value) => left = value - width;

  // 定义计算属性 bottom 的 getter
  double get bottom => top + height;

  // 定义计算属性 bottom 的 setter
  set bottom(double value) => top = value - height;

  @override
  String toString() =>
      'Rectangle(left: $left, top: $top, width: $width, height: $height)';
}

// --- 4. Abstract Methods (Doer Abstract Class) ---

// 定义一个抽象类
abstract class Doer {
  // 抽象类可以有实例变量、具体方法等...
  String taskName = "默认任务";

  // 定义一个抽象方法，只有声明，没有实现（用分号结束）
  void doSomething();

  // 抽象类也可以有具体方法
  void describeTask() {
    print('准备执行任务: $taskName');
  }
}

// 实现抽象类的具体类
class EffectiveDoer extends Doer {
  // 必须提供抽象方法 doSomething 的具体实现
  @override
  void doSomething() {
    // 这里提供具体的实现
    print('EffectiveDoer 正在努力地 "$taskName"... 完成！✨');
  }
}

// --- Main Function to Demonstrate Methods ---
void main() {
  print('--- 1. 演示实例方法 (Point) ---');
  var p1 = Point(2, 2);
  var p2 = Point(5, 6);
  var distance = p1.distanceTo(p2);
  print('$p1 到 $p2 的距离是: $distance');
  // 验证一下勾股定理：dx=3, dy=4, distance=sqrt(9+16)=5
  assert((distance - 5.0).abs() < 0.001); // 使用 assert 进行验证，并考虑浮点数精度
  print('');

  print('--- 2. 演示操作符 (Vector) ---');
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  final sum = v + w;
  print('$v + $w = $sum');
  assert(sum == Vector(4, 5)); // 使用重载的 == 操作符进行断言

  final diff = v - w;
  print('$v - $w = $diff');
  assert(diff == Vector(0, 1)); // 使用重载的 == 操作符进行断言

  print('Vector 操作符断言通过！✅');
  print('');

  print('--- 3. 演示 Getters 和 Setters (Rectangle) ---');
  var rect = Rectangle(3, 4, 20, 15);
  print('初始矩形: $rect');
  print('初始 rect.left: ${rect.left}');
  print('通过 getter 获取 rect.right: ${rect.right}'); // left + width = 3 + 20 = 23
  assert(rect.right == 23);

  // 使用 setter 修改 right 的值
  rect.right = 12;
  print('设置 rect.right = 12 后...');
  print('现在的 rect.left: ${rect.left}'); // left = value - width = 12 - 20 = -8
  print('现在的矩形: $rect');
  assert(rect.left == -8);

  print('Rectangle Getters/Setters 断言通过！✅');
  print('');

  print('--- 4. 演示抽象方法 (Doer/EffectiveDoer) ---');
  // 不能直接实例化抽象类 Doer
  // var impossible = Doer(); // 这行会报错

  // 实例化具体实现类
  var doer = EffectiveDoer();
  doer.taskName = "打扫房间"; // 可以访问继承的或自身的属性
  doer.describeTask(); // 调用继承的具体方法
  doer.doSomething(); // 调用实现的抽象方法
  print('');

  print('--- 所有演示完成 ---');
}
